package starlingui.state.desktopState
{
	import com.imcrl.core.StarlingHelper;
	import com.imcrl.core.imcrl_internal;
	import com.imcrl.event.AdvListItemEvent;
	import com.imcrl.event.ListItemEvent;
	
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	import starling.display.DisplayObjectContainer;
	import starling.display.Stage;
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.events.TouchPhase;
	
	import starlingui.component.AdvLayout;
	import starlingui.component.DeskList;
	import starlingui.component.Desktop;
	import starlingui.component.FolderList;
	import starlingui.component.itemRender.IconItemRender;
	import starlingui.component.page.AdvPage;
	import starlingui.vo.IconVO;
	
	use namespace imcrl_internal;
	public class ShakeState extends AbsState implements IFolderAction
	{
		public static const NAME:String="ShakeState";
		
		private var deskList:DeskList;
		private var folderList:FolderList;
		private var layout:AdvLayout;
		private var page:AdvPage;
		private var rect:Rectangle;
		public function ShakeState(desktop:Desktop)
		{
			super(desktop,NAME);
		}
		
		override public function start():void{
			desktop.scrollEnabeld=false;
			desktop._background.addEventListener(TouchEvent.TOUCH,backTouchHandler);
			desktop._cache_top.addEventListener(Event.TRIGGERED,hideHandle);
			desktop._cache_botton.addEventListener(Event.TRIGGERED,hideHandle);
			
			deskList=desktop.current as DeskList;
			
			folderList=desktop.folderList;
			layout=deskList.layout;
			page=desktop.data as AdvPage;
			
			var w:int=layout.itemW>>1;
			var h:int=layout.itemH>>1;
			var hw:int=w>>1;
			var hh:int=h>>1;
			rect=new Rectangle(hw,hh,hw+w,hh+h);
			shakeAll();
			
			
			desktop.addEventListener(TouchEvent.TOUCH,stageUpHandle);
		}
		
		protected function stageUpHandle(event:TouchEvent):void{
			var touch:Touch=event.getTouch(desktop);
			if(touch.phase==TouchPhase.ENDED){
				desktop.removeEventListener(TouchEvent.TOUCH,stageUpHandle);
				deskList.addEventListener(ListItemEvent.SELECTED,selectedHandle);
			}
		}
		
		private function hideHandle(event:Event):void{
			trace("t  "+event);
			
			desktop.hideFolder();
			
			layout.shakeAll(true);
			
			var item:IconItemRender;
			AdvLayout(folderList.layout).shakeAll(false);
			desktop.pointList.visible=true;
		}
		
		protected function selectedHandle(event:ListItemEvent):void{
			var deskList:DeskList=event.target as DeskList;
			var item:IconItemRender=deskList.selectedItem as IconItemRender;
			if(item.isFolder){
				shakeAndOpenFolder(item);
			}
		}
		
		
		/**
		 * 
		 * @param item
		 * @param top
		 * @param botton
		 * 
		 */		
		public function expandBy(itemRender:IconItemRender,top:int,botton:int,alpha:Number,touchable:Boolean):void{
			layout.expandBy(itemRender,top,botton,alpha,touchable);
		}
		
		
		private var mx0:int;
		private var my0:int;
		
		private var mx:int;
		private var my:int;
		
		private var isMouseDown:Boolean=false;
		protected function backTouchHandler(event:TouchEvent):void{
			var touch:Touch=event.getTouch(desktop);
			if(touch==null)return;
			
			var mouseCaption:Point=touch.getLocation(desktop);
			
			switch(touch.phase){
				case TouchPhase.BEGAN :
					
					mx=mx0=mouseCaption.x;
					my=my0=mouseCaption.x;
					
					isMouseDown=true;
					break;
				
				case TouchPhase.ENDED :
					isMouseDown=false;
					
					var dx:int=mouseCaption.x-mx0;
					var dy:int=mouseCaption.x-my0;
					
					if(dx==0 && dy==0){
						break;
					}
					
					var len:int=Math.sqrt(dx*dx+dy*dy);
					
					if(len>desktop.halfSceneW){
						var bool:Boolean;
						if(dx<0 || dy<0){
							bool=desktop.next(deskList);
						}else{
							bool=desktop.prev(deskList);
						}
						
						if(bool && desktop.hasEventListener(ListItemEvent.CHANGE)){
							desktop.dispatchEvent(new ListItemEvent(ListItemEvent.CHANGE));
						}
					}else{	
						desktop.back(deskList);
					}
					
					break;
				
				
				case TouchPhase.MOVED :
					if(isMouseDown==false)return;
					desktop.container.x+=mouseCaption.x-mx;
					mx=mouseCaption.x; 
					break;
			}
		}
		
		
		override public function end():void{
			shakeAll(false);
			
			
			clearTimeout(openFolderInterval);
			desktop.removeEventListener(TouchEvent.TOUCH,stageUpHandle);
			deskList.removeEventListener(ListItemEvent.SELECTED,selectedHandle);
			
			desktop._background.removeEventListener(TouchEvent.TOUCH,backTouchHandler);
			desktop._cache_top.removeEventListener(Event.TRIGGERED,hideHandle);
			desktop._cache_botton.removeEventListener(Event.TRIGGERED,hideHandle);
			
			desktop.scrollEnabeld=false;
			
		}
		
		public function get folderEndState():String{
			return NAME;
		}
		
		
		public function shakeAll(bool:Boolean=true):void{
			
			if(bool){
				folderList.addEventListener(AdvListItemEvent.ITEM_DRAG_RECOGNIZED,folderDragStartHandle);
				deskList.addEventListener(AdvListItemEvent.ITEM_DRAG_RECOGNIZED,dragStartHandle);
			}else{
				folderList.removeEventListener(AdvListItemEvent.ITEM_DRAG_RECOGNIZED,folderDragStartHandle);
				deskList.removeEventListener(AdvListItemEvent.ITEM_DRAG_RECOGNIZED,dragStartHandle);
			}
			if(desktop.folderIsOpened==false){
				layout.shakeAll(bool);
			}
			AdvLayout(folderList.layout).shakeAll(bool);
		}
		
		
		private function folderDragStartHandle(event:AdvListItemEvent):void{
			currentDragger=event.item as IconItemRender;
			StarlingHelper.startDrag(currentDragger);
			var parent:DisplayObjectContainer=currentDragger.parent;
			parent.setChildIndex(currentDragger,parent.numChildren-1);
			currentDragger.stage.addEventListener(TouchEvent.TOUCH,touchHandle2);
		}
		
		
		private var currentDragger:IconItemRender;
		private function dragStartHandle(event:AdvListItemEvent):void{
			currentDragger=event.item as IconItemRender;
			StarlingHelper.startDrag(currentDragger);
			var parent:DisplayObjectContainer=currentDragger.parent;
			parent.setChildIndex(currentDragger,parent.numChildren-1);
			currentDragger.stage.addEventListener(TouchEvent.TOUCH,touchHandle);
		}
		private function touchHandle(event:TouchEvent):void{
			var touch:Touch=event.touches[0];
			var index:int;
			switch(touch.phase){
				case TouchPhase.ENDED :
					
					var stage:Stage=touch.target.stage;
					stage.removeEventListener(TouchEvent.TOUCH,touchHandle);
					StarlingHelper.stopDrag(currentDragger);
					
					if(injectFolder){
						inject(injectFolder,currentDragger);
						injectFolder=null;
					}else{
						index=currentDragger.index;
						var p:Point=layout.getIndexPosition(currentDragger.index);
						currentDragger.tweenPropertys(["x","y"],[p.x,p.y]);
					}
					break;
				case TouchPhase.MOVED :
					
					var mx:int=currentDragger.x;
					var my:int=currentDragger.y;
					
					var cRow:int=my/layout.itemH;
					var cCol:int=Math.min(mx/layout.itemW,layout.col-1);
					
					
					var dx:Number=mx-cCol*layout.itemW;
					var dy:Number=my-cRow*layout.itemH;
					
					index=cRow*layout.col+cCol;
					var dragIndex:int=currentDragger.index;
					if(rect.contains(dx,dy)==false){
						if(injectFolder){
							trace(dragIndex,injectFolder.index,index);
							changeSlot(dragIndex,injectFolder.index);
							injectFolder.injectEnd(null);
							injectFolder=null;
						}
						break;
					}
					
					var list:Vector.<IconItemRender>=layout.getList();
					index=Math.min(list.length-1,index);
					
					
					if(currentDragger.isFolder==false){
						
						var inSlot:IconItemRender=injectCheck(dragIndex,index);
						
						if(inSlot){
							if(injectFolder && injectFolder !=inSlot){
								changeSlot(dragIndex,injectFolder.index);
								injectFolder.injectEnd(null);
							}
							injectFolder=inSlot;
							break;
						}else if(injectFolder){
							injectFolder.injectEnd(null);
							injectFolder=null;
						}
					}
					
					changeSlot(dragIndex,index);
					
					break;
			}
		}
		
		/**
		 * 对于文件夹内的文件拖动操作; 
		 * @param event
		 * 
		 */		
		private function touchHandle2(event:TouchEvent):void{
			var layout:AdvLayout=folderList.layout;
			var touch:Touch=event.touches[0];
			var index:int;
			switch(touch.phase){
				case TouchPhase.ENDED :
					
					var stage:Stage=touch.target.stage;
					stage.removeEventListener(TouchEvent.TOUCH,touchHandle2);
					StarlingHelper.stopDrag(currentDragger);
					
					
					index=currentDragger.index;
					var p:Point=layout.getIndexPosition(currentDragger.index);
					currentDragger.tweenPropertys(["x","y"],[p.x,p.y]);
					break;
				case TouchPhase.MOVED :
					
					var mx:int=currentDragger.x;
					var my:int=currentDragger.y;
					
					var cRow:int=my/layout.itemH;
					var cCol:int=Math.min(mx/layout.itemW,layout.col-1);
					
					
					var dx:Number=mx-cCol*layout.itemW;
					var dy:Number=my-cRow*layout.itemH;
					
					index=cRow*layout.col+cCol;
					var dragIndex:int=currentDragger.index;
					if(rect.contains(dx,dy)==false){
						break;
					}
					
					
					var list:Vector.<IconItemRender>=folderList.layout.getList();
					index=Math.min(list.length-1,index);
					
					changeSlot2(dragIndex,index);
					
					break;
			}
		}
		
		
		
		private function changeSlot(dragIndex:int,dropIndex:int):void{
			var b:Boolean=layout.changeSlot(dragIndex,dropIndex);
			if(b){
				page.changeSlot(deskList.index,dragIndex,dropIndex);
			}
		
		}
		
		
		/**
		 * 对于文件夹内位置调整 
		 * @param dragIndex
		 * @param dropIndex
		 * 
		 */		
		private function changeSlot2(dragIndex:int,dropIndex:int):void{
			if(dragIndex==dropIndex){
				return;
			}
			var layout:AdvLayout=folderList.layout;
			var b:Boolean=layout.changeSlot(dragIndex,dropIndex);
			if(b){
				page.subListChangeSlot(folderList.data,dragIndex,dropIndex);
			}
		}
		
		
		private var injectFolder:IconItemRender;
		private function injectCheck(dragIndex:int,dropIndex:int):IconItemRender{
			if(dragIndex==dropIndex)return null;
			
			var list:Vector.<IconItemRender>=layout.getList();
			var icon:IconItemRender=list[dropIndex];
			if(icon.isFull){
				return null;
			}
			
			icon.injectStart(list[dragIndex]);
			return icon;
		}
		
		
		/**
		 * 注入到文件夹中;(或者合并两个项) 
		 * @param injectFolder
		 * @param injectItem
		 * 
		 */		
		public function inject(injectFolder:IconItemRender,injectItem:IconItemRender):void{
			injectFolder.injectEnd(currentDragger);
			
			var folderVO:IconVO=injectFolder.data;
			if(folderVO.sub.length==0){
				var newVO:IconVO=new IconVO();
				newVO.icon=IconVO.FOLDER_PATH;
				newVO.sub.push(folderVO);
				
				folderVO=newVO;
			}
			folderVO.sub.push(injectItem.data);
			injectFolder.data=folderVO;
			
			
			page.repleaceData(deskList.index,injectFolder.index,folderVO);
			page.remove(deskList.index,injectItem.index);
			layout.removeItem(injectItem);
			
			clearTimeout(openFolderInterval);
			openFolderInterval=setTimeout(shakeAndOpenFolder,350,injectFolder);
		}
		
		private var openFolderInterval:int;
		
		
		/**
		 *  
		 * @param item
		 * 
		 */		
		public function shakeAndOpenFolder(item:IconItemRender):void{
			
			layout.shakeAll(false);
			
			desktop.selectedItem(item,deskList);
			desktop.pointList.visible=false;
			
			AdvLayout(folderList.layout).shakeAll(true);
		}
		
			
		override public function endByEvent(event:Event):void{
			if(desktop.folderIsOpened){
				desktop.setState(FolderState.NAME);
			}else{
				desktop.setState(DefaultState.NAME);
			}
		}
	}
}